﻿using HslCommunication.ModBus;
using jakaApi;
using jkType;
using Prism.Events;
using Prism.Mvvm;
using RoboAssembleX.Application.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using static jkType.JKTYPE;

namespace RoboAssembleX.Application.Robot
{
    public class RoboService
    {
        public RoboService(IEventAggregator eventAggregator,RoboModel roboModel)
        {
            this.eventAggregator = eventAggregator;
            this.roboModel = roboModel;
        }

        private readonly IEventAggregator eventAggregator;
        private readonly RoboModel roboModel;

        #region ReadData
        ModbusTcpNet modbus;
        Task monitorDataTask;
        public void SwitchReadData()
        {
            try
            {
                if (roboModel.ReadDataFlag)
                    roboModel.ReadDataFlag = false;
                else
                {
                    modbus = new ModbusTcpNet("192.168.0.100", 6502);
                    modbus.AddressStartWithZero = true;
                    modbus.DataFormat = HslCommunication.Core.DataFormat.CDAB;
                    var r = modbus.ConnectServer();
                    if (r.IsSuccess)
                    {
                        eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂Modbus连接成功", 1));
                        Task.Run(ReadDataJob);
                        //monitorDataTask = new Task(ReadDataJob);
                        //monitorDataTask.Start();
                        roboModel.ReadDataFlag = true;
                        eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂数据读取成功", 1));
                    }
                    else
                        roboModel.ReadDataFlag = false;
                    int handle = 0;
                    var result = jakaAPI.create_handler("192.168.0.100", ref handle);
                    eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂API连接成功", 1));
                }
            }
            catch (Exception ex)
            {
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"连接机械臂失败{ex.Message}", 1));
            }
        }
        async Task ReadDataJob()
        {
            while (roboModel.ReadDataFlag)
            {
                var result =await modbus.ReadBoolAsync("x=2;8", 12);
                if (result.IsSuccess)
                {
                    roboModel.DO1 = result.Content[0];
                    roboModel.DO2 = result.Content[1];
                    roboModel.DO3 = result.Content[2];
                    roboModel.DO4 = result.Content[3];
                    roboModel.DO5 = result.Content[4];
                    roboModel.DO6 = result.Content[5];
                    roboModel.DO7 = result.Content[6];
                    roboModel.DO8 = result.Content[7];
                    roboModel.DO9 = result.Content[8];
                    roboModel.DO10 = result.Content[9];
                    roboModel.DO11 = result.Content[10];
                    roboModel.DO12 = result.Content[11];
                }
                var result1 =await modbus.ReadUInt16Async("x=4;454", 6);
                if (result.IsSuccess)
                {
                    roboModel.CollisionStop = result1.Content[0]==1?true:false;
                    roboModel.EmergencyStop = result1.Content[1] == 1 ? true : false;
                    roboModel.PowerOn = result1.Content[2] == 1 ? true : false;
                    roboModel.RebotEnable = result1.Content[3] == 1 ? true : false;
                    roboModel.SoftLimit = result1.Content[4] == 1 ? true : false;
                    roboModel.InPos = result1.Content[5] == 1 ? true : false;
                }

                int handle = 0;
                JKTYPE.ProgramState state = new JKTYPE.ProgramState();
                var result2 = jakaAPI.get_program_state(ref handle, ref state);
                if (result2 == 0)
                {
                    switch (state)
                    {
                        case ProgramState.PROGRAM_IDLE:
                            roboModel.ProgramState = "未运行";
                            break;
                        case ProgramState.PROGRAM_RUNNING:
                            roboModel.ProgramState = "运行中";
                            break;
                        case ProgramState.PROGRAM_PAUSED:
                            roboModel.ProgramState = "已暂停";
                            break;
                    }
                }
               await Task.Delay(500);
            }
        }
        #endregion

        public async Task SwitchPowerOn()
        {
            int handle = 0;
            if (roboModel.PowerOn)
            {
                var result = jakaAPI.power_off(ref handle);
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂电源关闭", 1));
            }
            else
            {
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂电源正在打开...", 1));
                var result = jakaAPI.power_on(ref handle);
                int i = 10;
                while(i>0)
                {
                    if (roboModel.PowerOn)
                    {
                        i = 0;
                        eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂电源打开成功", 1));
                        return;
                    }
                    else
                    {
                        await Task.Delay(1000);
                        i -= 1;
                    }
                }
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂电源打开超时", 1));
            }
        }
        public void SwitchRoboEnable()
        {
            int handle = 0;
            if (roboModel.RebotEnable)
            {
                var result = jakaAPI.disable_robot(ref handle);
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂使能关闭", 1));
            }
            else
            {
                var result = jakaAPI.enable_robot(ref handle);
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂使能打开", 1));
            }
        }
        public void CollisionRecover()
        {
            int handle = 0;
            var result = jakaAPI.collision_recover(ref handle);
            eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂碰撞恢复完成", 1));
        }
        public void SwitchProgramRun()
        {
            int handle = 0;
            if (roboModel.ProgramState == "未运行")
            {
                var result = jakaAPI.program_run(ref handle);
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂关闭程序", 1));
            }
            else
            {
                var result = jakaAPI.program_abort(ref handle);
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"机械臂启动程序", 1));
            }

        }


        public async Task Action1Async()
        {
            var result = await modbus.WriteAsync("40", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO1 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result =await modbus.WriteAsync("40", false);
            }
        }

        public async Task Action2Async()
        {
            var result = await modbus.WriteAsync("41", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO2 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("41", false);
            }
        }

        public async Task Action3Async()
        {
            var result = await modbus.WriteAsync("42", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO3 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("42", false);
            }
        }

        public async Task Action4Async()
        {
            var result = await modbus.WriteAsync("43", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO4 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("43", false);
            }
        }

        public async Task Action5Async()
        {
            var result = await modbus.WriteAsync("44", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO5 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("44", false);
            }
        }

        public async Task Action6Async()
        {
            var result = await modbus.WriteAsync("45", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO6 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("45", false);
            }
        }

        public async Task Action7Async()
        {
            var result = await modbus.WriteAsync("46", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO7 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("46", false);
            }
        }

        public async Task Action8Async()
        {
            var result = await modbus.WriteAsync("47", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO8 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("47", false);
            }
        }

        public async Task Action9Async()
        {
            var result = await modbus.WriteAsync("48", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO9 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("48", false);
            }
        }

        public async Task Action10Async()
        {
            var result = await modbus.WriteAsync("49", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO10 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("49", false);
            }
        }

        public async Task Action11Async()
        {
            var result = await modbus.WriteAsync("50", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO11 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("50", false);
            }
        }

        public async Task Action12Async()
        {
            var result = await modbus.WriteAsync("51", true);
            await Task.Delay(500);
            if (result.IsSuccess)
            {
                int i = 10;
                while (!roboModel.DO12 && i > 0)
                {
                    await Task.Delay(1000);
                    i -= 1;
                }
                result = await modbus.WriteAsync("51", false);
            }
        }


        public async Task NextJobStatusAsync(bool readyStatus)
        {
            var result = await modbus.WriteAsync("70", readyStatus);
            await Task.Delay(500);
        }
    }
}
